﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using MediaRecommender.Model;

namespace MediaRecommender.Controller
{
    //Adds media to the users medialist and updates their vector representation
    public class MedialistController
    {
        private MediaList _userMedialist;

        public MediaList UserMediaList
        {
            get { return this._userMedialist; }
            private set { this._userMedialist = value; }
        }

        public MedialistController(User user)
        {
            MediaList returnedMediaList = user.MediaList;

            this.UserMediaList = returnedMediaList;
        }

        public void AddMedia(Media media, int rating)
        {
            if (rating > 10)
                rating = 10;
            if (rating < 0)
                rating = 0;

            if (this._userMedialist.ContainsKey(media))
                this._userMedialist[media] = rating;
            else
            {
                this._userMedialist.Add(media, rating);

                foreach (var variable in media.Genres)
                    this._userMedialist.VectorRepresentation[variable] += this.ConvertRating(rating);

                // Depending on the media type, update the users' associated person vector with the associated people from the media
                if (media is Book)
                {
                    Book bkey = (Book)media;

                    foreach (var author in bkey.Author)
                    {
                        this._userMedialist.AssociatedPeopleVector[author.ID] += this.ConvertRating(rating);
                    }
                }

                if (media is Movie)
                {
                    Movie mkey = (Movie)media;

                    this._userMedialist.AssociatedPeopleVector[mkey.Director.ID] += this.ConvertRating(rating);

                    foreach (var actor in mkey.Actors)
                    {
                        this._userMedialist.AssociatedPeopleVector[actor.ID] += this.ConvertRating(rating);
                    }
                }

                if (media is VideoGame)
                {
                    VideoGame vkey = (VideoGame)media;

                    this._userMedialist.AssociatedPeopleVector[vkey.Publisher.ID] += this.ConvertRating(rating);

                    this._userMedialist.AssociatedPeopleVector[vkey.Studio.ID] += this.ConvertRating(rating);
                }
            }
        }

        public bool RemoveMedia(Media media)
        {
            // Does the same as the add method, but works in reverse, updating the vectors to null the removed medias effect on the vector
            if (UserMediaList.ContainsKey(media))
            {
                foreach (var variable in media.Genres)
                {
                    if (this._userMedialist.User.Preferences.Contains(variable))
                    {
                        this._userMedialist.VectorRepresentation[variable] -= this.ConvertRating(UserMediaList[media]);
                    }
                    else
                    {
                        this._userMedialist.VectorRepresentation[variable] -= this.ConvertRating(UserMediaList[media]);
                    }
                }

                if (media is Book)
                {
                    Book bkey = (Book)media;

                    foreach (var author in bkey.Author)
                    {
                        this._userMedialist.AssociatedPeopleVector[author.ID] -= this.ConvertRating(UserMediaList[media]);
                    }
                }

                if (media is Movie)
                {
                    Movie mkey = (Movie)media;

                    this._userMedialist.AssociatedPeopleVector[mkey.Director.ID] -= this.ConvertRating(UserMediaList[media]);

                    foreach (var actor in mkey.Actors)
                    {
                        this._userMedialist.AssociatedPeopleVector[actor.ID] -= this.ConvertRating(UserMediaList[media]);
                    }
                }

                if (media is VideoGame)
                {
                    VideoGame vkey = (VideoGame)media;

                    this._userMedialist.AssociatedPeopleVector[vkey.Publisher.ID] -= this.ConvertRating(UserMediaList[media]);

                    this._userMedialist.AssociatedPeopleVector[vkey.Studio.ID] -= this.ConvertRating(UserMediaList[media]);
                }

                UserMediaList.UserMediaList.Remove(media);
                return true;
            }

            return false;
        }

        // Converts the rating into a number in the range of -1 to 1. Rating itself is in the range of 0 to 10
        private double ConvertRating(double rating)
        {
            return (rating / 5) - 1;
        }
    }
}